package com.jt.resource.controller;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.cloud.client.ServiceInstance;
import org.springframework.cloud.client.loadbalancer.LoadBalancerClient;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.client.RestTemplate;
//门面模式,中介者模式,模板方法,代理模式,策略)

/**
 * 定义服务消费端Controller,在这个Controller对象
 * 的方法中实现对远端服务sca-provider的调用
 */

@RestController
public class Cosumercontroller {
    //IOC-(资源整合-坐享其成)->Spring框架的目标(资源整合)
    //DI-依赖注入(属性注入,构造注入,set注入):注入之前要查找(依赖查找-DL)


    @Autowired  //属性注入 (但是属性不能使用final修饰)            DI=依赖注入   属性注入，构造注入，set注入 ，
    private RestTemplate restTemplate;

    @Value("${server.port:8080}")
    private String servicePort;



//    /**
//     * 基于此对象可以从nacos中动态获取服务列表,
//     * 并基于内置负载均衡算法获取服务实例,
//     * 这里的LoadBalancerClient是一个接口类型,
//     * 实际运行spring框架会为此接口类型的变量
//     * 注入一个实现类的对象.
//     */
    @Autowired
    private LoadBalancerClient  loadBalancerClient;




    /**
     * 定义服务调用,在此方法中我们通过restTemplate基于指定url
     * 调用远端服务.
     * @return
     */



        //方案1:自己写负载均衡算法
        //定义远端服务的url地址
        //String url1="http://localhost:8081/provider/echo/{msg}";
        //String url2="http://localhost:8082/provider/echo/{msg}";
        //String[] urlArray={url1,url2};
        //String url=urlArray[new Random().nextInt(urlArray.length)];
        //基于RestTemplate借助http协议向远端服务发起Get请求
        //return restTemplate.getForObject(url,
        //String.class,serverPort);//String.class为url对应服务的响应结果类型

    @GetMapping("/consumer/doRestEcho1")
    public String doRestEcho01(){
        //方案2:从nacos中动态获取服务列表,并基于内置负载均衡算法获取服务实例
        ServiceInstance  serviceinstance = loadBalancerClient.choose("sca-provider");
        //获取端口号
        String url="http://%s:%s/provider/echo/{msg}";
        String ip=serviceinstance.getHost();
        int port = serviceinstance.getPort();
        url = String.format(url, ip, port);

        return restTemplate.getForObject(url,String.class, servicePort);

    };




    @Autowired
    private RestTemplate loadBalancedRestTemplate;     //负载均衡方式的随机调用

    @GetMapping("/consumer/doRestEcho3")
    public String doRestEcho03() {
    //方案三
         //1)构建请求url,这个url使用服务名替换ip:port
        String url = String.format("http://%s/provider/echo/{msg}", "sca-provider");
        //2)实现服务调用(这里的RestTemplate必须具备基于服务名查找服务实例的能力)
        return loadBalancedRestTemplate.getForObject(url, String.class, servicePort);
        //如上语句在发起请求会被底层拦截器拦截,拦截器拦截到请求后,
        //还是会通过loadBalancerClient对象基于服务名获取服务实例
        //只是这个过程被底层做了,我们只时进行服务调用即可.
        //所以doRestEcho03相对于doRestEcho02来讲只是做了代码的简化.
        //知识点的学习: nacos.io
    }

    }






